package com.xindacloud.sms.portal.utils;

import com.google.i18n.phonenumbers.PhoneNumberMatch;
import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
import com.xindacloud.sms.portal.exception.ServiceException;
import com.xindacloud.sms.portal.vo.CheckPhoneNumberVO;

import java.util.Locale;
import java.util.Objects;
import java.util.Set;

import static com.google.i18n.phonenumbers.PhoneNumberUtil.getInstance;

public class PhoneUtil {

    private static PhoneNumberUtil phoneNumberUtil = getInstance();

    private static PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();

    private static PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();

    /**
     * 根据国家代码和手机号  判断手机号是否有效
     *
     * @param phoneNumber
     * @param countryCode
     * @return
     */
    public static boolean checkPhoneNumber(String phoneNumber, Integer countryCode) {

        long phone = Long.parseLong(phoneNumber);

        Phonenumber.PhoneNumber pn = new Phonenumber.PhoneNumber();
        pn.setCountryCode(countryCode);
        pn.setNationalNumber(phone);

        return phoneNumberUtil.isValidNumber(pn);

    }

    /**
     * 根据国家代码和手机号  判断手机运营商
     *
     * @param phoneNumber
     * @param countryCode
     * @return
     */
    public static String getCarrier(String phoneNumber, Integer countryCode) {

        long phone = Long.parseLong(phoneNumber);

        Phonenumber.PhoneNumber pn = new Phonenumber.PhoneNumber();
        pn.setCountryCode(countryCode);
        pn.setNationalNumber(phone);
        //返回结果只有英文，自己转成成中文
        String carrierEn = carrierMapper.getNameForNumber(pn, Locale.ENGLISH);
        String carrierZh = "";
        carrierZh += geocoder.getDescriptionForNumber(pn, Locale.CHINESE);
        switch (carrierEn) {
            case "China Mobile":
                carrierZh += "移动";
                break;
            case "China Unicom":
                carrierZh += "联通";
                break;
            case "China Telecom":
                carrierZh += "电信";
                break;
            default:
                break;
        }
        return carrierEn;
    }


    /**
     * @param phoneNumber
     * @param countryCode
     * @return 参数
     * @Description: 根据国家代码和手机号  手机归属地
     * @date 2017-4-26 上午11:33:18
     */
    public static String getGeo(String phoneNumber, Integer countryCode) {

        long phone = Long.parseLong(phoneNumber);

        Phonenumber.PhoneNumber pn = new Phonenumber.PhoneNumber();
        pn.setCountryCode(countryCode);
        pn.setNationalNumber(phone);

        return geocoder.getDescriptionForNumber(pn, Locale.US);

    }


    public static boolean checkPhoneNumber(String phoneNumber) {

        final Set<String> supportedRegions = phoneNumberUtil.getSupportedRegions();
        for (String region : supportedRegions) {
            final Iterable<PhoneNumberMatch> cn = phoneNumberUtil.findNumbers(phoneNumber, region);
            if (cn.iterator().hasNext()) {
                final PhoneNumberMatch phoneNumberMatch = cn.iterator().next();
                final Phonenumber.PhoneNumber number = phoneNumberMatch.number();
                final String combinedNumber = String.valueOf(number.getCountryCode()).concat(String.valueOf(number.getNationalNumber()));
                if (Objects.equals(combinedNumber, phoneNumber)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static CheckPhoneNumberVO getPoneNumber(String phoneNumber) {
        //final Set<Integer> supportedCallingCodes = phoneNumberUtil.getSupportedCallingCodes();
        try {
            final Set<String> supportedRegions = phoneNumberUtil.getSupportedRegions();
            for (String region : supportedRegions) {
                final Phonenumber.PhoneNumber parse = phoneNumberUtil.parse(phoneNumber, region);
                String combinedNumber;
                if (String.valueOf(parse.getNationalNumber()).startsWith(String.valueOf(parse.getCountryCode()))) {
                    combinedNumber = phoneNumber;
                } else {
                    combinedNumber = String.valueOf(parse.getCountryCode()).concat(String.valueOf(parse.getNationalNumber()));
                }
//                final String combinedNumber = String.valueOf(parse.getCountryCode()).concat(String.valueOf(parse.getNationalNumber()));
                final String countryCode = phoneNumberUtil.getRegionCodeForCountryCode(parse.getCountryCode());
                if (Objects.equals(combinedNumber, phoneNumber) && Objects.equals(countryCode, region)) {
                    return CheckPhoneNumberVO.builder()
                            .countryPrefix(parse.getCountryCode())
                            .nationalNumber(parse.getNationalNumber())
                            .region(region)
                            .build();
                }
            }
        } catch (Exception e) {
            throw new ServiceException("号码不合法.", UnionResultHelp.StatusEnum.ParamsFail.code());
        }
        return null;
    }
}
